package com.hades.xq.miaoshao.service.impl;

import com.hades.xq.miaoshao.dao.OrderDOMapper;
import com.hades.xq.miaoshao.dao.SequenceDOMapper;
import com.hades.xq.miaoshao.dataobject.OrderDO;
import com.hades.xq.miaoshao.dataobject.SequenceDO;
import com.hades.xq.miaoshao.error.BusinessException;
import com.hades.xq.miaoshao.error.EmBusinessError;
import com.hades.xq.miaoshao.service.ItemService;
import com.hades.xq.miaoshao.service.OrderService;
import com.hades.xq.miaoshao.service.UserService;
import com.hades.xq.miaoshao.service.model.ItemModel;
import com.hades.xq.miaoshao.service.model.OrderModel;
import com.hades.xq.miaoshao.service.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ItemService itemService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderDOMapper orderDOMapper;

    @Autowired
    private SequenceDOMapper sequenceDOMapper;

    @Transactional
    @Override
    public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) throws BusinessException {
        //step1: 校验下单状态：下单的商品是否存在，是否可售；下单用户是否合法；购买数量是否正确

        ItemModel itemModel = itemService.getItemById(itemId);
        if (itemModel == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品信息不存在");
        }

        UserModel userModel = userService.getUserById(userId);
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "用户信息不存在");
        }

        if (amount <= 0 || amount > 99) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "数量信息不正确");
        }

        //校验活动信息
        if (promoId != null && promoId > 0) {
            //1）校验对应活动是否存在于这个商品
            if (promoId.intValue() != itemModel.getPromoModel().getId()) {
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动信息不正确");
                //2）校验活动是否正在进行
            } else if (itemModel.getPromoModel().getStatus() != 2) {
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动还未开始");
            }
        }

        //step2: 落单减库存；支付减库存；我们采取落单减库存方式
        boolean result = itemService.decreaseStock(itemId, amount);
        if (!result) {
            throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
        }
        //step3: 订单入库
        OrderModel orderModel = new OrderModel();
        orderModel.setUserId(userId);
        orderModel.setAmount(amount);
        orderModel.setItemId(itemId);

        if (promoId != null) {
            orderModel.setItemPrice(itemModel.getPromoModel().getPromoItemPrice());
        } else {
            orderModel.setItemPrice(itemModel.getPrice());
        }
        orderModel.setPromoId(promoId);
        orderModel.setOrderPrice((orderModel.getItemPrice()).multiply(new BigDecimal(amount)));
        //step3.1: 生成订单号根据一定的规则
        orderModel.setId(generateOrderNo());

        OrderDO orderDO = convertFromOrderModel(orderModel);
        orderDOMapper.insertSelective(orderDO);

        //商品销量增加

        itemService.increaseSales(itemId, amount);

        //step4: 返回前端

        return orderModel;
    }

    /**
     * 生成订单号;不管当前订单是否生成，sequence都需要自增。避免重复情况
     * Propagation.REQUIRES_NEW：当前事物不管外部事物是否成功，当前事物都提交掉
     *
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    private String generateOrderNo() {
        //订单号总共16位
        StringBuilder stringBuilder = new StringBuilder();
        //step1: 前8位是时间信息，包含年月日
        LocalDateTime localDateTime = LocalDateTime.now();
        String nowTime = localDateTime.format(DateTimeFormatter.ISO_DATE).replace("-", "");
        stringBuilder.append(nowTime);
        //step2: 中间6位为自增序列
        //step2.1 获取sequence
        int sequence = 0;
        SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info");
        sequence = sequenceDO.getCurrentValue();
        sequenceDO.setCurrentValue(sequenceDO.getCurrentValue() + sequenceDO.getStep());
        sequenceDOMapper.updateByPrimaryKeySelective(sequenceDO);
        //凑足6位，不足的补0，没有设置最大的值
        String sequenceStr = String.valueOf(sequence);
        for (int i = 0; i < 6 - sequenceStr.length(); i++) {
            stringBuilder.append("0");
        }
        stringBuilder.append(sequenceStr);
        //step3: 最后2位是分库分表位置(00~99),暂时固定00
        stringBuilder.append("00");

        return stringBuilder.toString();
    }

    private OrderDO convertFromOrderModel(OrderModel orderModel) {
        if (orderModel == null) {
            return null;
        }
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(orderModel, orderDO);
        orderDO.setItemPrice(orderModel.getItemPrice().doubleValue());
        orderDO.setOrderPrice(orderModel.getOrderPrice().doubleValue());
        return orderDO;
    }
}
